<?php

namespace App\Http\Controllers\WxApi;

use App\Models\WxClient;
use App\Plugins\Wechat\Client;
use App\Plugins\Wechat\Messages;
use App\Services\WxClientService;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Plugins\Wechat\SETTING;
use Illuminate\Support\Facades\Cache;
use Helper;
use Illuminate\Support\Facades\Redis;

class IndexController extends Controller
{
    public function __construct()
    {
        $this->_repoService = new WxClientService();
    }

    public function loginClient($id) {
        $timeout = config('wxc.wait_timeout');
        $login_timeout = config('wxc.login_timeout');
        $client = WxClient::find($id);
        $uin = (!is_numeric($client->uin) OR empty($client->uin)) ? 0 : $client->uin;
        $status = 0;
        $uuid = Cache::get("wl_$id", $this->_getUuid($uin, $login_timeout));
        // 已获取到UUID
        if (!empty($uuid)) {
            $status = $this->_getStatus($uuid, $client);
            if ($status > 0 && $status == $uin) {
                Cache::forget("wl_$id");
            } else {
                Cache::put("wl_$id", $uuid, $login_timeout / 60);
            }
        } else { // 未获取到UUID
            Redis::publish(SETTING::CMD_CHANNEL_NAME, json_encode([
                'action' => 'start',
                'uin' => $uin,
                'debug' => config('app.debug'),
            ]));
            $startTime = time();
            while (empty($uuid)) { // 等待获取uuid
                $endTime = time();
                // 20秒超时时间
                if ($endTime - $startTime > $timeout*2) {
                    break;
                }
                $uuid = $this->_getUuid($uin, $login_timeout);
            }

            if (!empty($uuid)) {
                Cache::put("wl_$id", $uuid, $login_timeout / 60);
                $status = SETTING::LOGIN_STARTING;
                if ($timeout > $login_timeout) {
                    $timeout = $login_timeout + 1;
                }
            } else {
                // 没有获取到uuid,检查一下是否是断点登录
                $status = $this->_getStatus($client->uuid, $client);
            }
        }
        // 根据登录状态返回信号
        Helper::initEventSource();
        $message = view('wx.ess')
            ->with('id', $status)
            ->with('timeout', $timeout * 1000)
            ->with('content', $uuid);
        exit($message);
    }

    protected function _getUuid($uin, &$timeout) {
        if ($uin === 0) { // 当前微信号没有记录过UIN
            $_uuid = Redis::rpop(SETTING::FREE_UUID_LIST);
        } else { // 当前微信号已记录UIN
            $key = sprintf(SETTING::UIN_MAP_UUID, $uin);
            $_uuid = Redis::get($key);
            $timeout = Redis::ttl($key);
        }
        return $_uuid ?? '';
    }

    protected function _getStatus($uuid, $client) {
        $status = Redis::zscore(SETTING::UUID_LOGIN_STATUS, $uuid);
        if ($status > 10000) {
            $client->uuid = $uuid;
            if (!is_numeric($client->uin) OR empty($client->uin)) {
                $client->uin = (int) $status;
            }
            $client->save();
            Redis::zrem(SETTING::UUID_LOGIN_STATUS, $uuid);
        }
        return $status ?? 0;
    }

    public function updateInfo($id) {
        $wx_client = WxClient::find($id);
        if (is_null($wx_client)) {
            return $this->_error('该微信不存在');
        }
        $result = Client::updateInfo($wx_client->uin);
        if ($result) {
            sleep(1.5); // 等待1.5s
            return Client::isActive($wx_client->uin);
        } else {
            return $this->_error('操作失败');
        }
    }

    public function clearInfo($id) {
        $wx_client = WxClient::find($id);
        if (is_null($wx_client)) {
            return $this->_error('该微信不存在');
        }
        $result = Client::removeInfo($wx_client->uin);
        if ($result) {
            return 'modify success';
        } else {
            return $this->_error('操作失败');
        }
    }
}
